#!/usr/bin/python
# -*- coding: utf-8 -*-

#Author: Yuanhao Li <jay_21cn@hotmail.com>
#File: ingcview.py
#Usage: Client of ING from project Babel
#Copyright (C) 2007 Yuanhao Li<jay_21cn@hotmail.com>

#This program is free software; you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 2 of the License, or
#(at your option) any later version.

#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.

#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software Foundation,
#Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

#本程序是遵从 GPL 2.0 许可发布的. 你可以自由修改和再发布本程序, 
#但请遵守 GPL 2.0 条款, 尊重知识产权.

import sys, os, time, thread, urllib

from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QString, QRegExp, QThread

from view_ui import Ui_Form
from ingcrss import IngRss
from babel import Babel
from ingcthreads import ThreadLogin, ThreadGetNewItems, ThreadRequestHotTopics
import ingcinfobase as Info

cwd = os.path.split(sys.argv[0])[0]
if not cwd:
	cwd = os.getcwd()

class IngcView(Ui_Form, QtCore.QObject):
	def __init__(self, url, usr, usrpwd, proxy, ingcapp, tab):
		QtCore.QObject.__init__(self)
		self.setupUi(tab)
		self.proxy = proxy
		self.babel = Babel(url, usr, usrpwd, proxy)
		self.threadLogin = ThreadLogin(self.babel)
		self.threadRequestHotTopics = ThreadRequestHotTopics(self.babel)
		self.alternateHandle = False
		self.doLogined = False
		self.reconnected = False
		self.stack = []
		self.ingcApp = ingcapp
		self.setting = self.ingcApp.setting
		self.settingGroup = usr + '@' + QtCore.QString(url).remove('http://', QtCore.Qt.CaseInsensitive)
		self.setting.beginGroup('MainWindow')
		fontString = self.setting.value('font', QtCore.QVariant(QtCore.QString('Sans Serif,14,-1,5,50,0,0,0,0,0'))).toString()
		self.font = QtGui.QFont()
		self.font.fromString(fontString)
		self.setFont(self.font)
		self.setting.endGroup()

		QtCore.QObject.connect(self.threadLogin, QtCore.SIGNAL("doLogin"), self.onLogin)
		QtCore.QObject.connect(self.threadRequestHotTopics, QtCore.SIGNAL("finished()"), self.displayHotTopics)
		QtCore.QObject.connect(self.babel, QtCore.SIGNAL("AddIngTimeOut"), self.addIngTimeOut)

	def addIngTimeOut(self, ing):
		self.appendSysMessage(Info.IngcAddIngTimeOut)
		self.textBrowser.append(QString(u'<table cellpadding = "10" border="0"><tr><td><span style= "color: #333333;"> <b>未发送:</b> ') + ing + QString(u'</span></td></tr></table>'))

	def getUrl(self):
		return self.babel.getUrl()

	def isLogined(self):
		return self.doLogined

	def isReconnected(self):
		return self.reconnected

	def doLogin(self):
		self.appendSysMessage(Info.IngcViewStartLoginMessage)
		self.threadLogin.start()

	def onLogin(self):
		if self.babel.logined is True:
			self.appendSysMessage(Info.IngcLoginSuccess)
			self.rss = IngRss(self.babel.getUrl(), self.babel.getUserNickname(), self.proxy)
			self.setting.beginGroup('accounts')
			self.setting.beginGroup(self.settingGroup)
			self.mode = self.setting.value('mode', QtCore.QVariant('friends')).toString()
			self.period = self.setting.value('period', QtCore.QVariant('30')).toInt()[0]
			self.rss.setCurrentUsingUrl(self.mode)
			self.emit(QtCore.SIGNAL('modeChanged'), self)
			self.emit(QtCore.SIGNAL('periodChanged'), self)
			self.setting.endGroup()
			self.setting.endGroup()
			QtCore.QObject.connect(self.rss, QtCore.SIGNAL("parseNewItemsError"), self.parseNewItemsError)
			self.threadGetNewItems = ThreadGetNewItems(self.rss)
			self.threadGetNewItems.setSleepTime(self.period)
			QtCore.QObject.connect(self.threadGetNewItems, QtCore.SIGNAL("hasNewItems"), self.displayNewItems)
			QtCore.QObject.connect(self.threadGetNewItems, QtCore.SIGNAL("requestedOnce"), self.setLastUpdateTime)
			self.threadGetNewItems.start()
			self.doLogined = True
			self.reconnected = True
		else:
			self.appendSysMessage(Info.IngcLoginFailed)

	def parseNewItemsError(self):
		if self.doLogined is True:
			self.doLogined = False
			self.threadGetNewItems.setRunning(False)
			self.appendSysMessage(Info.IngcParseNewItemsError)
			self.ingcApp.ui.actionReconnect.setEnabled(True)
			self.ingcApp.ui.actionReconnect.setShortcut(QtGui.QApplication.translate("MainWindow", "Ctrl+R", None, QtGui.QApplication.UnicodeUTF8))
			self.ingcApp.ui.actionDisconnect.setEnabled(False)
			self.ingcApp.ui.actionDisconnect.setShortcut(QtGui.QApplication.translate("MainWindow", "", None, QtGui.QApplication.UnicodeUTF8))
			self.ingcApp.ui.textEdit.setEnabled(False)

	def disconnect(self):
		if self.doLogined is True:
			self.doLogined = False
			self.threadGetNewItems.setRunning(False)
			self.appendSysMessage(Info.IngcDisconnect)

	def reconnect(self):
		self.doLogined = True
		self.threadGetNewItems.setRunning(True)
		self.threadGetNewItems.start()
		self.appendSysMessage(Info.IngcReconnect)

	def appendSysMessage(self, dic):
		template = Info.IngcDisplayTemplate().getSysTemplate()
		template.replace(QString('$contentcolor_qwer1234'), dic['content'])
		self.textBrowser.append(template)

	def displayHotTopics(self):
		self.textBrowser.setUpdatesEnabled(False)
		self.textBrowser.append(self.threadRequestHotTopics.content)
		self.textBrowser.setUpdatesEnabled(True)

	def appendNewEntry(self, dic):
		template = Info.IngcDisplayTemplate().getTemplate()
		if dic["userDisplayPicture"].contains('http://', QtCore.Qt.CaseInsensitive):
			template.replace(QString('$displaypicture_qwer1234'), dic["userDisplayPicture"])
		else:
			template.replace(QString('$displaypicture_qwer1234'), QString('<img src="pixmaps/wrongPicture.png">'))
		template.replace(QString('$userprofileurl_qwer1234'), QString(self.babel.getUrl()) + QString('/u/') + urllib.quote(dic['userNickname'].toUtf8()))
		template.replace(QString('$nickname_qwer1234'), dic['userNickname'])
		template.replace(QString('$content_qwer1234'), dic['content'])
		template.replace(QString('$date_qwer1234'), dic['date'])
		if self.doLogined is False:
			if self.alternateHandle is False:
				template.replace(QString('$alternatecolor_qwer1234'), Info.IngcEntryColor1)
				self.alternateHandle = True
			else:
				template.replace(QString('$alternatecolor_qwer1234'), Info.IngcEntryColor2)
				self.alternateHandle = False
		else:
			if QString(dic['content']).contains(QString(self.babel.getUserNickname()), QtCore.Qt.CaseInsensitive):
				template.replace(QString('$alternatecolor_qwer1234'), Info.IngcEntryColor3)
				template.replace(QString('$contentcolor_qwer1234'), Info.IngcEntryColor7)
				template.replace(QString('$idcolor_qwer1234'), Info.IngcEntryColor7)
			else:
				template.replace(QString('$contentcolor_qwer1234'), Info.IngcEntryColor6)
				if self.alternateHandle is False:
					template.replace(QString('$alternatecolor_qwer1234'), Info.IngcEntryColor1)
					self.alternateHandle = True
				else:
					template.replace(QString('$alternatecolor_qwer1234'), Info.IngcEntryColor2)
					self.alternateHandle = False
				if QString(dic['userNickname']) == QString(self.babel.getUserNickname()):
					template.replace(QString('$idcolor_qwer1234'), Info.IngcEntryColor4)
				else:
					template.replace(QString('$idcolor_qwer1234'), Info.IngcEntryColor5)
		template.replace(QString('align="absmiddle" '), QString(''))
		self.textBrowser.append(template)

	def displayNewItems(self):
		self.textBrowser.setUpdatesEnabled(False)
		self.textBrowser.thread().setPriority(QThread.TimeCriticalPriority)
		for i in self.rss.getItems():
			self.appendNewEntry(i)
		self.emit(QtCore.SIGNAL("newItemsComing"), self)
		self.textBrowser.setUpdatesEnabled(True)

	def setLastUpdateTime(self):
		self.updateTime = time.strftime("%H:%M:%S", time.localtime())
		self.emit(QtCore.SIGNAL("requestedOnce2"), self)

	def setFont(self, font):
		self.font = font
		styleCandidate = ['normal', 'italic', 'oblique']
		family = font.family()
		size = font.pixelSize()
		if size < 0:
			size = font.pointSize()
		style = styleCandidate[font.style()]
		weight = 'normal'
		if font.weight() != 50:
			weight = 'bold'
		stylesheet = 'QTextBrowser{font-family: "' + family + '"; font-size: ' + str(size) + 'px; font-style: ' + style + '; font-weight: ' + weight + ';}'
		self.textBrowser.setStyleSheet(stylesheet)
		m = self.textBrowser.verticalScrollBar().maximum()
		self.textBrowser.verticalScrollBar().setSliderPosition(m)

	def receiveUserCommand(self, cmd):
		cmd = cmd.simplified()
		cmdlist = cmd.split(' ')
		command = cmdlist[0]
		content = cmdlist[1:].join(' ')
		if (command == QString('ingc') or command == QString('Ingc') or command == QString('INGC')) and self.doLogined is True:
			if content != QString('') and len(content) < 132:
				thread.start_new_thread(self.babel.addIng, (content,))
				return True
			else:
				self.appendSysMessage(Info.IngcIngTooBig)
				return False
		elif (command == QString('help') or command == QString('Help') or command == QString('HELP')) and self.doLogined is True:
			self.appendSysMessage(Info.IngcHelpText)
			return True
		elif (command == QString('me') or command == QString('Me') or command == QString('ME')) and self.doLogined is True:
			self.rss.setCurrentUsingUrl('me')
			self.appendSysMessage(Info.IngcChangeToMe)
			self.mode = 'me'
			self.emit(QtCore.SIGNAL("modeChanged"), self)
			self.setting.beginGroup('accounts')
			self.setting.beginGroup(self.settingGroup)
			self.setting.setValue('mode', QtCore.QVariant('me'))
			self.setting.endGroup()
			self.setting.endGroup()
			return True
		elif (command == QString('friends') or command == QString('Friends') or command == QString('FRIENDS')) and self.doLogined is True:
			self.rss.setCurrentUsingUrl('friends')
			self.appendSysMessage(Info.IngcChangeToFriends)
			self.mode = 'friends'
			self.emit(QtCore.SIGNAL("modeChanged"), self)
			self.setting.beginGroup('accounts')
			self.setting.beginGroup(self.settingGroup)
			self.setting.setValue('mode', QtCore.QVariant('friends'))
			self.setting.endGroup()
			self.setting.endGroup()
			return True
		elif (command == QString('everyone') or command == QString('Everyone') or command == QString('EVERYONE')) and self.doLogined is True:
			self.rss.setCurrentUsingUrl('everyone')
			self.appendSysMessage(Info.IngcChangeToEveryone)
			self.mode = 'everyone'
			self.emit(QtCore.SIGNAL("modeChanged"), self)
			self.setting.beginGroup('accounts')
			self.setting.beginGroup(self.settingGroup)
			self.setting.setValue('mode', QtCore.QVariant('everyone'))
			self.setting.endGroup()
			self.setting.endGroup()
			return True
		elif (command == QString('jay') or command == QString('Jay') or command == QString('JAY')) and self.doLogined is True:
			self.appendSysMessage(Info.IngcJay)
		elif (command == QString('hot') or command == QString('Hot') or command == QString('HOT')) and self.doLogined is True:
			self.threadRequestHotTopics.start()
			return True
		elif (command == QString('period') or command == QString('Period') or command == QString('PERIOD')) and self.doLogined is True:
			if content == QString(''):
				self.appendSysMessage(Info.IngcUpdateError)
			else:
				t = content.toInt()
				if t[1] and t[0] != 0:
					self.threadGetNewItems.setSleepTime(t[0])
					self.period = t[0]
					self.emit(QtCore.SIGNAL("periodChanged"), self)
					self.setting.beginGroup('accounts')
					self.setting.beginGroup(self.settingGroup)
					self.setting.setValue('period', QtCore.QVariant(t[0]))
					self.setting.endGroup()
					self.setting.endGroup()
				else:
					self.appendSysMessage(Info.IngcUpdateError)
			return True
		elif (command == QString('font') or command == QString('Font') or command == QString('FONT')) and self.doLogined is True:
			font = QtGui.QFontDialog.getFont(self.font)
			if font[1] is True:
				fontString = font[0].toString()
				self.setting.beginGroup('MainWindow')
				self.setting.setValue('font', QtCore.QVariant(fontString))
				self.setting.endGroup()
				self.ingcApp.changeFont(font[0])
			else:
				#self.appendSysMessage(Info.IngcFontError)
				pass
			return True
		else:
			self.appendSysMessage(Info.IngcHelp)
			return False
